'use strict';

const cp = require('child_process'); 
const path = require('path');

const Package = require('@dmj-cli/package');
const log = require('@dmj-cli/log');

const SETTINGS = {
    init: '@imooc-cli/init'
};

const CACHE_DIR = 'dependencies';

async function exec() {
    let targetPath = process.env.CLI_TARGET_PATH;
    let storeDir = '';
    let pkg;
    const homePath = process.env.CLI_HOME_PATH;
    log.verbose('targetPath', targetPath);
    log.verbose('homePath', homePath);

    const cmdObj = arguments[arguments.length - 1];
    const cmdName = cmdObj.name();
    const packageName = SETTINGS[cmdName];
    const packageVersion = 'latest';
    if (!targetPath) {
        // 生成缓存路径
        targetPath = path.resolve(homePath, CACHE_DIR);
        // 2、modulePath => package(npm模块)
        storeDir = path.resolve(targetPath, 'node_modules');
        log.verbose('targetPath', targetPath);
        log.verbose('storeDir', storeDir);

        // 1、根据targetPath => modulePath
        pkg = new Package({
            targetPath,
            packageName,
            packageVersion,
            storeDir
        });
        if (await pkg.exists()) {
            // 更新package
            await pkg.update();
        } else {
            // 安装package
            await pkg.install();
        }
    } else {
        pkg = new Package({
            targetPath,
            packageName,
            packageVersion
        });
    }
    // 3、Package.getRootFile(获取入口文件)
    const rootFile = pkg.getRootFilePath();
    if (rootFile) {
        // 在当前进程中调用 为异步
        try {
            const args = Array.from(arguments);
            const cmd = {
                ...args[args.length - 1],
                ...args[args.length -2]
            }
            const o = Object.create(null);
            Object.keys(cmd).forEach(key => {
                if (cmd.hasOwnProperty(key) && !key.startsWith('_') && key !== 'parent') {
                    o[key] = cmd[key]
                }
            })
            args[args.length - 1] = o;
            const code = `require('${rootFile}').call(null, ${JSON.stringify(args)});`;
            const child = spawn('node', ['-e', code], {
                cwd: process.cwd(),
                stdio: 'inherit'
            });
            child.on('error', e => {
                log.error(e.message);
                process.exit(1);
            })
            child.on('exit', e => {
                log.verbose('命令执行成功:' + e);
            })
        } catch (error) {
            log.error(error.message)
        }
    }
}

function spawn(command, args, options) {
    const win32 = process.platform === 'win32';
    const cmd = win32 ? 'cmd' : command;
    // /c表示静默执行 在window上
    const cmdArgs = win32 ? ['/c'].concat(command, args) : args;
    return cp.spawn(cmd, cmdArgs, options || {});
}

module.exports = exec;